package com.himiotech.core.project.data.dao;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.*;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.util.*;

/**
 * @author wuwenbin
 * @see HimioJdbc
 */
@Slf4j
@Repository
public class HimioJdbcImpl implements HimioJdbc {

    private final DataSource dataSource;
    private final JdbcTemplate jdbcTemplate;
    private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Autowired
    public HimioJdbcImpl(DataSource dataSource) {
        this.dataSource = dataSource;
        this.jdbcTemplate = new JdbcTemplate(dataSource);
        this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    }

    private static String calcCountSql(String nativeSql) {
        final String countSql = "COUNT(0)";
        Assert.hasText(nativeSql, "sql is not correct!");
        String sql = nativeSql.toUpperCase();
        if (sql.contains("DISTINCT(") || sql.contains(" GROUP BY ")) {
            return "SELECT " + countSql + " FROM (" + nativeSql + ") TEMP_COUNT_TABLE";
        }
        String[] froms = sql.split(" FROM ");
        String tempSql = "";
        for (int i = 0; i < froms.length; i++) {
            if (i != froms.length - 1) {
                tempSql = tempSql.concat(froms[i] + " FROM ");
            } else {
                tempSql = tempSql.concat(froms[i]);
            }
            int left = tempSql.split("\\(").length;
            int right = tempSql.split("\\)").length;
            if (left == right) {
                break;
            }
        }
        tempSql = " FROM " + nativeSql.substring(tempSql.length(), sql.length());
        int orderBy = tempSql.toUpperCase().indexOf(" ORDER BY ");
        if (orderBy >= 0) {
            tempSql = tempSql.substring(0, orderBy);
        }
        return "SELECT " + countSql + " ".concat(tempSql);
    }

    private static String decorateMysqlPageLimit(final String sql, Page<?> page) {
        String querySql = sql;
        long pageNo = page.getCurrent();
        long pageSize = page.getSize();
        if (pageNo > 0 && pageSize > 0) {
            long pageFirst = (pageNo - 1) * pageSize;
            querySql = querySql.concat(" LIMIT " + pageFirst + "," + pageSize);
        }
        return querySql;
    }

    private <T> RowMapper<T> createRowMapper(Class<T> clazz) {
        return BeanPropertyRowMapper.newInstance(clazz);
    }

    private MapSqlParameterSource createArraySqlParamSource(String key, Object value) {
        return new MapSqlParameterSource(key, value);
    }

    private MapSqlParameterSource createMapSqlParamSource(Map<String, ?> m) {
        return new MapSqlParameterSource(m);
    }

    private BeanPropertySqlParameterSource createBeanSqlParamSource(Object o) {
        return new BeanPropertySqlParameterSource(o);
    }

    private String getTableNameFromInsertSql(String sql) {
        sql = sql.toLowerCase();
        int firstLeft = sql.indexOf("(");
        int into = sql.indexOf("into");
        int values = sql.indexOf("values");
        if (firstLeft > values) {
            return sql.substring(into + 5, values);
        }
        if (firstLeft < values) {
            return sql.substring(into + 5, firstLeft);
        }
        throw new RuntimeException("获取表名失败！");
    }

    @Override
    public DataSource getCurrentDataSource() {
        return this.dataSource;
    }

    @Override
    public JdbcTemplate getJdbcTemplateObj() {
        return jdbcTemplate;
    }

    @Override
    public NamedParameterJdbcTemplate getNamedParameterJdbcTemplateObj() {
        return this.namedParameterJdbcTemplate;
    }

    @Override
    public Connection getConnection() throws Exception {
        return this.dataSource.getConnection();
    }

    @Override
    public int insertMapAutoGenKeyReturnAffect(String sql, Map<String, Object> mapParameter) {
        Assert.hasText(sql, "sql语句不正确！");
        Assert.notNull(mapParameter, "对象mapParameter不能为空");
        log.info("==> SQL: {}" , sql);
        log.info("==> SQL参数：[{}]" , mapParameter);
        GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
        return namedParameterJdbcTemplate.update(sql, createMapSqlParamSource(mapParameter), keyHolder);
    }

    @Override
    public int insertBeanAutoGenKeyReturnAffect(String sql, Object beanParameter) {
        Assert.hasText(sql, "sql语句不正确！");
        Assert.notNull(beanParameter, "对象beanParameter不能为空");
        log.info("==> SQL: {}" , sql);
        log.info("==> SQL参数：[{}]" , beanParameter);
        GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
        return namedParameterJdbcTemplate.update(sql, createBeanSqlParamSource(beanParameter), keyHolder);
    }

    @Override
    public long insertMapAutoGenKeyReturnKey(String sql, Map<String, Object> mapParameter) {
        Assert.hasText(sql, "sql语句不正确！");
        Assert.notNull(mapParameter, "对象mapParameter不能为空");
        log.info("==> SQL: {}" , sql);
        log.info("==> SQL参数：[{}]" , mapParameter);
        GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
        namedParameterJdbcTemplate.update(sql, createMapSqlParamSource(mapParameter), keyHolder);
        return keyHolder.getKey().longValue();
    }

    @Override
    public long insertBeanAutoGenKeyReturnKey(String sql, Object beanParameter) {
        Assert.hasText(sql, "sql语句不正确！");
        Assert.notNull(beanParameter, "对象beanParameter不能为空");
        log.info("==> SQL: {}" , sql);
        log.info("==> SQL参数：[{}]" , beanParameter);
        GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
        namedParameterJdbcTemplate.update(sql, createBeanSqlParamSource(beanParameter), keyHolder);
        return Objects.requireNonNull(keyHolder.getKey()).longValue();
    }

    @Override
    public Map<String, Object> insertMapAutoGenKeyReturnMap(String insertSql, Map<String, Object> mapParameter, String pkName) {
        String tableName = getTableNameFromInsertSql(insertSql);
        long key = insertMapAutoGenKeyReturnKey(insertSql, mapParameter);
        String sql = "SELECT * FROM ".concat(tableName).concat(" WHERE ").concat(pkName).concat(" = ?");
        return findMapByArray(sql, key);
    }

    @Override
    public <T> T insertMapAutoGenKeyReturnBean(String insertSql, Map<String, Object> mapParameter, Class<T> clazz, String pkName) {
        String tableName = getTableNameFromInsertSql(insertSql);
        long key = insertMapAutoGenKeyReturnKey(insertSql, mapParameter);
        String sql = "SELECT * FROM ".concat(tableName).concat(" WHERE ").concat(pkName).concat(" = ?");
        return findBeanByArray(sql, clazz, key);
    }

    @Override
    public <T> T insertBeanAutoGenKeyReturnBean(String insertSql, Object beaParameter, Class<T> clazz, String pkName) {
        String tableName = getTableNameFromInsertSql(insertSql);
        long key = insertBeanAutoGenKeyReturnKey(insertSql, beaParameter);
        String sql = "SELECT * FROM ".concat(tableName).concat(" WHERE ").concat(pkName).concat(" = ?");
        return findBeanByArray(sql, clazz, key);
    }

    @Override
    public Map<String, Object> insertBeanAutoGenKeyReturnMap(String insertSql, Object beanParameter, String pkName) {
        String tableName = getTableNameFromInsertSql(insertSql);
        long key = insertBeanAutoGenKeyReturnKey(insertSql, beanParameter);
        String sql = "SELECT * FROM ".concat(tableName).concat(" WHERE ").concat(pkName).concat(" = ?");
        return findMapByArray(sql, key);
    }

    @Override
    public int executeArray(String sql, Object... arrayParameters) {
        Assert.hasText(sql, "sql语句不正确!");
        log.info("==> SQL: {}" , sql);
        log.info("==> SQL参数：[{}]" , arrayParameters);
        int affectCount;
        if (arrayParameters != null && arrayParameters.length > 0) {
            affectCount = jdbcTemplate.update(sql, arrayParameters);
        } else {
            affectCount = jdbcTemplate.update(sql);
        }
        log.info("<== 响应条目：[{}]" , affectCount);
        return affectCount;
    }

    @Override
    public int executeMap(String sql, Map<String, Object> mapParameter) {
        Assert.hasText(sql, "sql语句不正确!");
        int affectCount;
        if (mapParameter != null && mapParameter.size() > 0) {
            log.info("==> SQL: {}" , sql);
            log.info("==> SQL参数：[{}]" , mapParameter);
            affectCount = namedParameterJdbcTemplate.update(sql, mapParameter);
            log.info("<== 响应条目：[{}]" , affectCount);
        } else {
            affectCount = executeArray(sql);
        }
        return affectCount;
    }

    @Override
    public int executeBean(String sql, Object beanParameter) {
        Assert.hasText(sql, "sql语句不正确!");
        int affectCount;
        if (beanParameter != null) {
            log.info("==> SQL: {}" , sql);
            log.info("==> SQL参数：[{}]" , beanParameter);
            affectCount = namedParameterJdbcTemplate.update(sql, createBeanSqlParamSource(beanParameter));
            log.info("<== 响应条目：[{}]" , affectCount);
        } else {
            affectCount = executeArray(sql);
        }
        return affectCount;
    }

    @SafeVarargs
    @Override
    public final int[] executeBatchByArrayMaps(String sql, Map<String, Object>... mapParameters) {
        Assert.hasText(sql, "sql语句不正确!");
        log.info("==> SQL: {}" , sql);
        log.info("==> SQL参数：[{}]" , Arrays.toString(mapParameters));
        if ((mapParameters != null) && (mapParameters.length > 0)) {
            SqlParameterSource[] mapSqlParamSource = SqlParameterSourceUtils.createBatch(mapParameters);
            int[] affects = namedParameterJdbcTemplate.batchUpdate(sql, mapSqlParamSource);
            log.info("<== 响应条目：[{}]" , Arrays.toString(affects));
            return affects;
        }
        return null;
    }

    @Override
    public int[] executeBatchByArrayBeans(String sql, Object... beanParameters) {
        Assert.hasText(sql, "sql语句不正确!");
        log.info("==> SQL: {}" , sql);
        log.info("==> SQL参数：[{}]" , Arrays.toString(beanParameters));
        if (beanParameters != null && beanParameters.length > 0) {
            SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(beanParameters);
            int[] affects = namedParameterJdbcTemplate.batchUpdate(sql, batch);
            log.info("<== 响应条目：[{}]" , Arrays.toString(affects));
            return affects;
        }
        return null;
    }

    @Override
    public int[] executeBatchByCollectionMaps(String sql, Collection<Map<String, Object>> mapParameters) {
        Assert.hasText(sql, "sql语句不正确!");
        log.info("==> SQL: {}" , sql);
        log.info("==> SQL参数：[{}]" , mapParameters);
        if (mapParameters != null && !mapParameters.isEmpty()) {
            //noinspection unchecked
            Map<String, Object>[] mps = mapParameters.toArray(new Map[0]);
            int[] affects = namedParameterJdbcTemplate.batchUpdate(sql, mps);
            log.info("<== 响应条目：[{}]" , Arrays.toString(affects));
            return affects;
        }
        return null;
    }

    @Override
    public int[] executeBatchByCollectionBeans(String sql, Collection<?> beanParameters) {
        Assert.hasText(sql, "sql语句不正确!");
        log.info("==> SQL: {}" , sql);
        log.info("==> SQL参数：[{}]" , beanParameters);
        if (beanParameters != null && !beanParameters.isEmpty()) {
            SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(beanParameters.toArray());
            int[] affects = namedParameterJdbcTemplate.batchUpdate(sql, batch);
            log.info("<== 响应条目：[{}]" , Arrays.toString(affects));
            return affects;
        }
        return null;
    }

    @Override
    public Number queryNumberByArray(String sql, Object... arrayParameters) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            log.info("==> SQL: {}" , sql);
            log.info("==> SQL参数：[{}]" , arrayParameters);
            if (arrayParameters != null && arrayParameters.length > 0) {
                return jdbcTemplate.queryForObject(sql, Number.class, arrayParameters);
            } else {
                return jdbcTemplate.queryForObject(sql, Number.class);
            }
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result!" , e);
            return 0;
        }
    }

    @Override
    public <T extends Number> T findNumberByArray(String sql, Class<T> numberClass, Object... arrayParameters) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            log.info("==> SQL: {}" , sql);
            log.info("==> SQL参数：[{}]" , arrayParameters);
            if (arrayParameters != null && arrayParameters.length > 0) {
                Number n = jdbcTemplate.queryForObject(sql, numberClass, arrayParameters);
                if (n == null) {
                    return NumberUtils.parseNumber("0" , numberClass);
                }
                //noinspection unchecked,CastCanBeRemovedNarrowingVariableType
                return (T) n;
            } else {
                Number n = jdbcTemplate.queryForObject(sql, numberClass);
                if (n == null) {
                    return NumberUtils.parseNumber("0" , numberClass);
                } else {
                    //noinspection CastCanBeRemovedNarrowingVariableType,unchecked
                    return (T) n;
                }
            }
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return NumberUtils.parseNumber("0" , numberClass);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result!" , e);
            return NumberUtils.parseNumber("0" , numberClass);
        }
    }

    @Override
    public Number queryNumberByMap(String sql, Map<String, Object> mapParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            if (mapParameter != null) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , mapParameter);
                return namedParameterJdbcTemplate.queryForObject(sql, mapParameter, Number.class);
            } else {
                return queryNumberByArray(sql);
            }
        } catch (EmptyResultDataAccessException ere) {
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("not result!" , e);
            return 0;
        }
    }

    @Override
    public <T extends Number> T findNumberByMap(String sql, Class<T> numberClass, Map<String, Object> mapParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            if (mapParameter != null && mapParameter.size() > 0) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , mapParameter);
                Number n = namedParameterJdbcTemplate.queryForObject(sql, mapParameter, numberClass);
                if (n == null) {
                    return NumberUtils.parseNumber("0" , numberClass);
                } else {
                    //noinspection unchecked,CastCanBeRemovedNarrowingVariableType
                    return (T) n;
                }
            } else {
                Number n = queryNumberByArray(sql, numberClass);
                if (n == null) {
                    return NumberUtils.parseNumber("0" , numberClass);
                } else {
                    //noinspection unchecked
                    return (T) n;
                }
            }
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return NumberUtils.parseNumber("0" , numberClass);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return NumberUtils.parseNumber("0" , numberClass);
        }
    }

    @Override
    public Number queryNumberByBean(String sql, Object beanParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            if (beanParameter != null) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , beanParameter);
                return namedParameterJdbcTemplate.queryForObject(sql, createBeanSqlParamSource(beanParameter), Number.class);
            } else {
                return queryNumberByArray(sql);
            }
        } catch (EmptyResultDataAccessException ere) {
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return 0;
        }
    }

    @Override
    public <T extends Number> T findNumberByBean(String sql, Class<T> numberClass, Object beanParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            if (beanParameter != null) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , beanParameter);
                Number n = namedParameterJdbcTemplate.queryForObject(sql, createBeanSqlParamSource(beanParameter), numberClass);
                if (n == null) {
                    return NumberUtils.parseNumber("0" , numberClass);
                } else {
                    //noinspection CastCanBeRemovedNarrowingVariableType,unchecked
                    return (T) n;
                }
            } else {
                Number n = queryNumberByArray(sql, numberClass);
                if (n == null) {
                    return NumberUtils.parseNumber("0" , numberClass);
                } else {
                    //noinspection unchecked
                    return (T) n;
                }
            }
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return NumberUtils.parseNumber("0" , numberClass);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return NumberUtils.parseNumber("0" , numberClass);
        }
    }

    @Override
    public <T> T findPrimitiveByArray(String sql, Class<T> objClass, Object... arrayParameters) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            log.info("==> SQL: {}" , sql);
            log.info("==> SQL参数：[{}]" , arrayParameters);
            if (arrayParameters != null && arrayParameters.length > 0) {
                return jdbcTemplate.queryForObject(sql, objClass, arrayParameters);
            } else {
                return jdbcTemplate.queryForObject(sql, objClass);
            }
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public <T> T findPrimitiveByMap(String sql, Class<T> objClass, Map<String, Object> mapParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            if (mapParameter != null && mapParameter.size() > 0) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , mapParameter);
                return namedParameterJdbcTemplate.queryForObject(sql, mapParameter, objClass);
            } else {
                return findPrimitiveByArray(sql, objClass);
            }
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public <T> T findPrimitiveByBean(String sql, Class<T> objClass, Object beanParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            if (beanParameter != null) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , beanParameter);
                return namedParameterJdbcTemplate.queryForObject(sql, createBeanSqlParamSource(beanParameter), objClass);
            } else {
                return findPrimitiveByArray(sql, objClass);
            }
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public Map<String, Object> findMapByArray(String sql, Object... arrayParameters) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            log.info("==> SQL: {}" , sql);
            log.info("==> SQL参数：[{}]" , arrayParameters);
            if (arrayParameters != null && arrayParameters.length > 0) {
                return jdbcTemplate.queryForMap(sql, arrayParameters);
            } else {
                return jdbcTemplate.queryForMap(sql);
            }
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public Map<String, Object> findMapByMap(String sql, Map<String, Object> mapParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            if (mapParameter != null && mapParameter.size() > 0) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , mapParameter);
                return namedParameterJdbcTemplate.queryForMap(sql, mapParameter);
            } else {
                return findMapByArray(sql);
            }
        } catch (EmptyResultDataAccessException ere) {
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public Map<String, Object> findMapByBean(String sql, Object beanParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            if (beanParameter != null) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , beanParameter);
                return namedParameterJdbcTemplate.queryForMap(sql, createBeanSqlParamSource(beanParameter));
            } else {
                return findMapByArray(sql);
            }
        } catch (EmptyResultDataAccessException ere) {
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public <T> T findBeanByArray(String sql, Class<T> clazz, Object... arrayParameters) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            Assert.notNull(clazz, "类集合中对象类型不能为空!");
            log.info("==> SQL: {}" , sql);
            log.info("==> SQL参数：[{}]" , arrayParameters);
            if (arrayParameters != null && arrayParameters.length > 0) {
                return jdbcTemplate.queryForObject(sql, createRowMapper(clazz), arrayParameters);
            } else {
                return jdbcTemplate.queryForObject(sql, createRowMapper(clazz));
            }
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public <T> T findBeanByMap(String sql, Class<T> clazz, Map<String, Object> mapParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            Assert.notNull(clazz, "集合中对象类型不能为空!");
            if (mapParameter != null && mapParameter.size() > 0) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , mapParameter);
                return namedParameterJdbcTemplate.queryForObject(sql, mapParameter, createRowMapper(clazz));
            } else {
                return findBeanByArray(sql, clazz);
            }
        } catch (EmptyResultDataAccessException e) {
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public <T> T findBeanByBean(String sql, Class<T> clazz, Object beanParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确！");
            Assert.notNull(clazz, "集合中对象类型不能为空！");
            if (beanParameter != null) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , beanParameter);
                return namedParameterJdbcTemplate.queryForObject(sql, createBeanSqlParamSource(beanParameter), createRowMapper(clazz));
            } else {
                return findBeanByArray(sql, clazz);
            }
        } catch (EmptyResultDataAccessException ere) {
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public <T> List<T> findListPrimitiveByArray(String sql, Class<T> objClass, Object... arrayParameters) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            log.info("==> SQL: {}" , sql);
            log.info("==> SQL参数：[{}]" , arrayParameters);
            List<T> list;
            if (arrayParameters != null && arrayParameters.length > 0) {
                list = jdbcTemplate.queryForList(sql, objClass, arrayParameters);
            } else {
                list = jdbcTemplate.queryForList(sql, objClass);
            }
            log.info("<== 响应条目：[{}]" , list.size());
            return list;
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public <T> List<T> findListPrimitiveByMap(String sql, Class<T> objClass, Map<String, Object> mapParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            List<T> list;
            if (mapParameter != null && mapParameter.size() > 0) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , mapParameter);
                list = namedParameterJdbcTemplate.queryForList(sql, mapParameter, objClass);
                log.info("<== 响应条目：[{}]" , list.size());
            } else {
                list = findListPrimitiveByArray(sql, objClass);
            }
            return list;
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public <T> List<T> findListPrimitiveByBean(String sql, Class<T> objClass, Object beanParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            List<T> list;
            if (beanParameter != null) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , beanParameter);
                list = namedParameterJdbcTemplate.queryForList(sql, createBeanSqlParamSource(beanParameter), objClass);
                log.info("<== 响应条目：[{}]" , list.size());
            } else {
                list = findListPrimitiveByArray(sql, objClass);
            }
            return list;
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public List<Map<String, Object>> findListMapByArray(String sql, Object... arrayParameters) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            log.info("==> SQL: {}" , sql);
            log.info("==> SQL参数：[{}]" , arrayParameters);
            List<Map<String, Object>> list;
            if (arrayParameters != null && arrayParameters.length > 0) {
                list = jdbcTemplate.queryForList(sql, arrayParameters);
            } else {
                list = jdbcTemplate.queryForList(sql);
            }
            log.info("<== 响应条目：[{}]" , list.size());
            return list;
        } catch (EmptyResultDataAccessException e) {
            log.info("<== 查询SQL无结果，{}" , e.getMessage());
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public List<Map<String, Object>> findListMapByMap(String sql, Map<String, Object> mapParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            List<Map<String, Object>> list;
            if (mapParameter != null && mapParameter.size() > 0) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , mapParameter);
                list = namedParameterJdbcTemplate.queryForList(sql, mapParameter);
                log.info("<== 响应条目：[{}]" , list.size());
            } else {
                list = findListMapByArray(sql);
            }
            return list;
        } catch (EmptyResultDataAccessException ere) {
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public List<Map<String, Object>> findListMapByBean(String sql, Object beanParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            List<Map<String, Object>> list;
            if (beanParameter != null) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , beanParameter);
                list = namedParameterJdbcTemplate.queryForList(sql, createBeanSqlParamSource(beanParameter));
                log.info("<== 响应条目：[{}]" , list.size());
            } else {
                list = findListMapByArray(sql);
            }
            return list;
        } catch (EmptyResultDataAccessException ere) {
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public <T> List<T> findListBeanByArray(String sql, Class<T> clazz, Object... arrayParameters) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            Assert.notNull(clazz, "集合中对象类型不能为空!");
            log.info("==> SQL: {}" , sql);
            log.info("==> SQL参数：[{}]" , arrayParameters);
            List<T> list;
            if (arrayParameters != null && arrayParameters.length > 0) {
                list = jdbcTemplate.query(sql, createRowMapper(clazz), arrayParameters);
            } else {
                list = jdbcTemplate.query(sql, createRowMapper(clazz));
            }
            log.info("<== 响应条目：[{}]" , list.size());
            return list;
        } catch (EmptyResultDataAccessException e) {
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public <T> List<T> findListBeanByMap(String sql, Class<T> clazz, Map<String, Object> mapParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            Assert.notNull(clazz, "集合中对象类型不能为空!");
            List<T> list;
            if (mapParameter != null && mapParameter.size() > 0) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , mapParameter);
                list = namedParameterJdbcTemplate.query(sql, mapParameter, createRowMapper(clazz));
                log.info("<== 响应条目：[{}]" , list.size());
            } else {
                list = findListBeanByArray(sql, clazz);
            }
            return list;
        } catch (EmptyResultDataAccessException ere) {
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public <T> List<T> findListBeanByBean(String sql, Class<T> clazz, Object beanParameter) {
        try {
            Assert.hasText(sql, "sql语句不正确!");
            Assert.notNull(clazz, "集合中对象类型不能为空!");
            List<T> list;
            if (beanParameter != null) {
                log.info("==> SQL: {}" , sql);
                log.info("==> SQL参数：[{}]" , beanParameter);
                list = namedParameterJdbcTemplate.query(sql, createBeanSqlParamSource(beanParameter), createRowMapper(clazz));
                log.info("<== 响应条目：[{}]" , list.size());
            } else {
                list = findListBeanByArray(sql, clazz);
            }
            return list;
        } catch (EmptyResultDataAccessException ere) {
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("<==! 查询SQL异常 no result! " , e);
            return null;
        }
    }

    @Override
    public Page<Map<String, Object>> findPageListMapByArray(String sql, Page<Map<String, Object>> page, Object... arrayParameters) {
        Assert.notNull(page, "分页信息不能为空");
        Assert.hasText(sql, "sql语句不正确!");
        long count;
        if (page.isSearchCount()) {
            count = findNumberByArray(calcCountSql(sql), Long.class, arrayParameters);
            page.setTotal(count);
        }
        List<Map<String, Object>> list = findListMapByArray(decorateMysqlPageLimit(sql, page), arrayParameters);
        page.setRecords(list);
        return page;
    }

    @Override
    public Page<Map<String, Object>> findPageListMapByMap(String sql, Page<Map<String, Object>> page, Map<String, Object> mapParameter) {
        Assert.notNull(page, "分页信息不能为空");
        Assert.hasText(sql, "sql语句不正确!");
        long count;
        if (page.isSearchCount()) {
            count = findNumberByMap(calcCountSql(sql), Long.class, mapParameter);
            page.setTotal((int) count);
        }
        List<Map<String, Object>> list = findListMapByMap(decorateMysqlPageLimit(sql, page), mapParameter);
        page.setRecords(list);
        return page;
    }

    @Override
    public <T> Page<T> findPageListBeanByArray(String sql, Class<T> clazz, Page<T> page, Object... arrayParameters) {
        Assert.notNull(page, "分页信息不能为空");
        Assert.hasText(sql, "sql语句不正确!");
        long count;
        if (page.isSearchCount()) {
            count = findNumberByArray(calcCountSql(sql), Long.class, arrayParameters);
            page.setTotal((int) count);
        }
        List<T> list = findListBeanByArray(decorateMysqlPageLimit(sql, page), clazz, arrayParameters);
        page.setRecords(list);
        return page;
    }

    @Override
    public <T> Page<T> findPageListBeanByMap(String sql, Class<T> clazz, Page<T> page, Map<String, Object> mapParameter) {
        Assert.notNull(page, "分页信息不能为空");
        Assert.hasText(sql, "sql语句不正确!");
        long count;
        if (page.isSearchCount()) {
            count = findNumberByMap(calcCountSql(sql), Long.class, mapParameter);
            page.setTotal((int) count);
        }
        List<T> list = findListBeanByMap(decorateMysqlPageLimit(sql, page), clazz, mapParameter);
        page.setRecords(list);
        return page;
    }

    @Override
    public <T> Page<T> findPageListBeanByBean(String sql, Class<T> clazz, Page<T> page, Object beanParameter) {
        Assert.notNull(page, "分页信息不能为空");
        Assert.hasText(sql, "sql语句不正确!");
        long count;
        if (page.isSearchCount()) {
            count = findNumberByBean(calcCountSql(sql), Long.class, beanParameter);
            page.setTotal((int) count);
        }
        List<T> list = findListBeanByBean(decorateMysqlPageLimit(sql, page), clazz, beanParameter);
        page.setRecords(list);
        return page;
    }


}